home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 2 / AACD 2.iso / AACD / Magazine / GraphicsCards / StormMesa / demos / reflect.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-12-15  |  9.4 KB  |  418 lines

  1. /* $Id: reflect.c,v 3.0 1998/02/14 18:42:29 brianp Exp $ */
  2.  
  3. /*
  4.  * Demo of a reflective, texture-mapped surface with OpenGL.
  5.  * Brian Paul   August 14, 1995   This file is in the public domain.
  6.  *
  7.  * Hardware texture mapping is highly recommended!
  8.  *
  9.  * The basic steps are:
  10.  *    1. Render the reflective object (a polygon) from the normal viewpoint,
  11.  *       setting the stencil planes = 1.
  12.  *    2. Render the scene from a special viewpoint:  the viewpoint which
  13.  *       is on the opposite side of the reflective plane.  Only draw where
  14.  *       stencil = 1.  This draws the objects in the reflective surface.
  15.  *    3. Render the scene from the original viewpoint.  This draws the
  16.  *       objects in the normal fashion.  Use blending when drawing
  17.  *       the reflective, textured surface.
  18.  *
  19.  * This is a very crude demo.  It could be much better.
  20.  */
  21.  
  22. /*
  23.  * Dirk Reiners (reiners@igd.fhg.de) made some modifications to this code.
  24.  *
  25.  * August 1996 - A few optimizations by Brian
  26.  */
  27.  
  28. /*
  29.  * April, 1997 - Added Mark Kilgard's changes.
  30.  */
  31.  
  32. /*
  33.  * $Log: reflect.c,v $
  34.  * Revision 3.0  1998/02/14 18:42:29  brianp
  35.  * initial rev
  36.  *
  37.  */
  38.  
  39.  
  40. #define USE_ZBUFFER
  41.  
  42.  
  43. /* OK, without hardware support this is overkill. */
  44. #define USE_TEXTURE
  45.  
  46. #include <math.h>
  47. #include <stdio.h>
  48. #include <stdlib.h>
  49. #include "GL/glut.h"
  50.  
  51. #ifndef AMIGA
  52. #include "../util/readtex.c"   /* I know, this is a hack. */
  53. #else
  54. GLubyte *LoadRGBImage( const char *, GLint *, GLint *, GLenum *);
  55. #endif
  56.  
  57.  
  58. #define DEG2RAD (3.14159/180.0)
  59.  
  60.  
  61. #define TABLE_TEXTURE "reflect.rgb"
  62.  
  63. static int ImgWidth, ImgHeight;
  64. static GLenum ImgFormat;
  65. static GLubyte *Image = NULL;
  66.  
  67. #define MAX_OBJECTS 2
  68.  
  69. static GLint table_list;
  70. static GLint objects_list[MAX_OBJECTS];
  71.  
  72.  
  73. static GLfloat xrot, yrot;
  74. static GLfloat spin;
  75.  
  76.  
  77.  
  78. static void make_table( void )
  79. {
  80.    static GLfloat table_mat[] = { 1.0, 1.0, 1.0, 0.6 };
  81.    static GLfloat gray[] = { 0.4, 0.4, 0.4, 1.0 };
  82.  
  83.    table_list = glGenLists(1);
  84.    glNewList( table_list, GL_COMPILE );
  85.  
  86.    /* load table's texture */
  87.    glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, table_mat );
  88. /*   glMaterialfv( GL_FRONT, GL_EMISSION, gray );*/
  89.    glMaterialfv( GL_FRONT, GL_DIFFUSE, table_mat );
  90.    glMaterialfv( GL_FRONT, GL_AMBIENT, gray );
  91.    
  92.    /* draw textured square for the table */
  93.    glPushMatrix();
  94.    glScalef( 4.0, 4.0, 4.0 );
  95.    glBegin( GL_POLYGON );
  96.    glNormal3f( 0.0, 1.0, 0.0 );
  97.    glTexCoord2f( 0.0, 0.0 );   glVertex3f( -1.0, 0.0,  1.0 );
  98.    glTexCoord2f( 1.0, 0.0 );   glVertex3f(  1.0, 0.0,  1.0 );
  99.    glTexCoord2f( 1.0, 1.0 );   glVertex3f(  1.0, 0.0, -1.0 );
  100.    glTexCoord2f( 0.0, 1.0 );   glVertex3f( -1.0, 0.0, -1.0 );
  101.    glEnd();
  102.    glPopMatrix();
  103.  
  104.    glDisable( GL_TEXTURE_2D );
  105.  
  106.    glEndList();
  107. }
  108.  
  109.  
  110. static void make_objects( void )
  111. {
  112.    GLUquadricObj *q;
  113.  
  114.    static GLfloat cyan[] = { 0.0, 1.0, 1.0, 1.0 };
  115.    static GLfloat green[] = { 0.2, 1.0, 0.2, 1.0 };
  116.    static GLfloat black[] = { 0.0, 0.0, 0.0, 0.0 };
  117.  
  118.    q = gluNewQuadric();
  119.    gluQuadricDrawStyle( q, GLU_FILL );
  120.    gluQuadricNormals( q, GLU_SMOOTH );
  121.  
  122.    objects_list[0] = glGenLists(1);
  123.    glNewList( objects_list[0], GL_COMPILE );
  124.    glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, cyan );
  125.    glMaterialfv( GL_FRONT, GL_EMISSION, black );
  126.    gluCylinder( q, 0.5, 0.5,  1.0, 15, 10 );
  127.    glEndList();
  128.  
  129.    objects_list[1] = glGenLists(1);
  130.    glNewList( objects_list[1], GL_COMPILE );
  131.    glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green );
  132.    glMaterialfv( GL_FRONT, GL_EMISSION, black );
  133.    gluCylinder( q, 1.5, 0.0,  2.5, 15, 10 );
  134.    glEndList();
  135. }
  136.  
  137.  
  138. static GLfloat light_pos[] = { 0.0, 20.0, 0.0, 1.0 };
  139.  
  140. static void init( void )
  141. {
  142.    make_table();
  143.    make_objects();
  144.  
  145.    /* Setup texture */
  146. #ifdef USE_TEXTURE
  147.  
  148.    Image = LoadRGBImage( TABLE_TEXTURE, &ImgWidth, &ImgHeight, &ImgFormat );
  149.    if (!Image) {
  150.       printf("Couldn't read %s\n", TABLE_TEXTURE);
  151.       exit(0);
  152.    }
  153.  
  154.    gluBuild2DMipmaps(GL_TEXTURE_2D, 3, ImgWidth, ImgHeight,
  155.                      ImgFormat, GL_UNSIGNED_BYTE, Image);
  156.  
  157.    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
  158.    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
  159.    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
  160.    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
  161. #endif
  162.  
  163.  
  164.    xrot = 30.0;
  165.    yrot = 50.0;
  166.    spin = 0.0;
  167.  
  168. #ifndef USE_ZBUFFER
  169.    glEnable( GL_CULL_FACE );
  170. #endif
  171.  
  172.    glShadeModel( GL_FLAT );
  173.    
  174.    glEnable( GL_LIGHT0 );
  175.    glEnable( GL_LIGHTING );
  176.  
  177.    glClearColor( 0.5, 0.5, 0.5, 1.0 );
  178.  
  179.    glEnable( GL_NORMALIZE );
  180. }
  181.  
  182.  
  183.  
  184. static void reshape(int w, int h)
  185. {
  186.    GLfloat aspect = (float) w / (float) h;
  187.  
  188.    glViewport(0, 0, w, h);
  189.    glMatrixMode(GL_PROJECTION);
  190.    glLoadIdentity();
  191.    glFrustum( -aspect, aspect, -1.0, 1.0, 4.0, 300.0 );
  192.    glMatrixMode(GL_MODELVIEW);
  193.    glLoadIdentity();
  194. }
  195.  
  196.  
  197.  
  198. static void draw_objects( GLfloat eyex, GLfloat eyey, GLfloat eyez )
  199. {
  200. #ifndef USE_ZBUFFER
  201.         if (eyex<0.5)
  202.         {
  203. #endif
  204.            glPushMatrix();
  205.            glTranslatef( 1.0, 1.5, 0.0 );
  206.            glRotatef( spin, 1.0, 0.5, 0.0 );
  207.            glRotatef( 0.5*spin, 0.0, 0.5, 1.0 );
  208.            glCallList( objects_list[0] );
  209.            glPopMatrix();
  210.         
  211.            glPushMatrix();
  212.            glTranslatef( -1.0, 0.85+3.0*fabs( cos(0.01*spin) ), 0.0 );
  213.            glRotatef( 0.5*spin, 0.0, 0.5, 1.0 );
  214.            glRotatef( spin, 1.0, 0.5, 0.0 );
  215.            glScalef( 0.5, 0.5, 0.5 );
  216.            glCallList( objects_list[1] );
  217.            glPopMatrix();
  218. #ifndef USE_ZBUFFER
  219.         }
  220.         else
  221.         {       
  222.            glPushMatrix();
  223.            glTranslatef( -1.0, 0.85+3.0*fabs( cos(0.01*spin) ), 0.0 );
  224.            glRotatef( 0.5*spin, 0.0, 0.5, 1.0 );
  225.            glRotatef( spin, 1.0, 0.5, 0.0 );
  226.            glScalef( 0.5, 0.5, 0.5 );
  227.            glCallList( objects_list[1] );
  228.            glPopMatrix();
  229.  
  230.            glPushMatrix();
  231.            glTranslatef( 1.0, 1.5, 0.0 );
  232.            glRotatef( spin, 1.0, 0.5, 0.0 );
  233.            glRotatef( 0.5*spin, 0.0, 0.5, 1.0 );
  234.            glCallList( objects_list[0] );
  235.            glPopMatrix();
  236.         }
  237. #endif
  238. }
  239.  
  240.  
  241.  
  242. static void draw_table( void )
  243. {
  244.    glCallList( table_list );
  245. }
  246.  
  247.  
  248.  
  249. static void draw_scene( void )
  250. {
  251.    GLfloat dist = 20.0;
  252.    GLfloat eyex, eyey, eyez;
  253.  
  254.    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
  255.  
  256.  
  257.    eyex = dist * cos(yrot*DEG2RAD) * cos(xrot*DEG2RAD);
  258.    eyez = dist * sin(yrot*DEG2RAD) * cos(xrot*DEG2RAD);
  259.    eyey = dist * sin(xrot*DEG2RAD);
  260.  
  261.    /* view from top */
  262.    glPushMatrix();
  263.    gluLookAt( eyex, eyey, eyez, 0.0, 0.0, 0.0,  0.0, 1.0, 0.0 );
  264.  
  265.    glLightfv( GL_LIGHT0, GL_POSITION, light_pos );
  266.  
  267.    /* draw table into stencil planes */
  268.    glEnable( GL_STENCIL_TEST );
  269. #ifdef USE_ZBUFFER
  270.    glDisable( GL_DEPTH_TEST );
  271. #endif
  272.    glStencilFunc( GL_ALWAYS, 1, 0xffffffff );
  273.    glStencilOp( GL_REPLACE, GL_REPLACE, GL_REPLACE );
  274.    glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE );
  275.    draw_table();
  276.    glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
  277.  
  278. #ifdef USE_ZBUFFER
  279.    glEnable( GL_DEPTH_TEST );
  280. #endif
  281.  
  282.  
  283.    /* render view from below (reflected viewport) */
  284.    /* only draw where stencil==1 */
  285.    if (eyey>0.0) {
  286.       glPushMatrix();
  287.  
  288.       glStencilFunc( GL_EQUAL, 1, 0xffffffff );  /* draw if ==1 */
  289.       glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
  290.       glScalef( 1.0, -1.0, 1.0 );
  291.  
  292.       /* Reposition light in reflected space. */
  293.       glLightfv(GL_LIGHT0, GL_POSITION, light_pos);
  294.  
  295.       draw_objects(eyex, eyey, eyez);
  296.       glPopMatrix();
  297.  
  298.       /* Restore light's original unreflected position. */
  299.       glLightfv(GL_LIGHT0, GL_POSITION, light_pos);
  300.    }
  301.  
  302.    glDisable( GL_STENCIL_TEST );
  303.  
  304.    glEnable( GL_BLEND );
  305.    glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
  306.  
  307. #ifdef USE_TEXTURE
  308.    glEnable( GL_TEXTURE_2D );
  309. #endif
  310.    draw_table();
  311.    glDisable( GL_TEXTURE_2D );
  312.    glDisable( GL_BLEND );
  313.  
  314.    /* view from top */
  315.    glPushMatrix();
  316.  
  317.    draw_objects(eyex, eyey, eyez);
  318.  
  319.    glPopMatrix();
  320.  
  321.    glPopMatrix();
  322.  
  323.    glutSwapBuffers();
  324. }
  325.  
  326.  
  327.  
  328. #if 0
  329. void draw_scene(void)
  330. {
  331.    GLfloat dist = 20.0;
  332.    GLfloat eyex, eyey, eyez;
  333.  
  334.    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
  335.  
  336.  
  337.    eyex = dist * cos(yrot*DEG2RAD) * cos(xrot*DEG2RAD);
  338.    eyez = dist * sin(yrot*DEG2RAD) * cos(xrot*DEG2RAD);
  339.    eyey = dist * sin(xrot*DEG2RAD);
  340.  
  341.    /* view from top */
  342.    glPushMatrix();
  343.    gluLookAt( eyex, eyey, eyez, 0.0, 0.0, 0.0,  0.0, 1.0, 0.0 );
  344.  
  345.    draw_table();
  346.  
  347.    glPopMatrix();
  348.  
  349.    glutSwapBuffers();
  350. }
  351. #endif
  352.  
  353.  
  354. static void Key( unsigned char key, int x, int y )
  355. {
  356.    if (key==27)
  357.       exit(0);
  358. }
  359.  
  360.  
  361. static void SpecialKey( int key, int x, int y )
  362. {
  363.    switch (key) {
  364.       case GLUT_KEY_UP:
  365.          xrot += 3.0;
  366. #ifndef USE_ZBUFFER
  367.                  if ( xrot > 180 )      xrot = 180;
  368. #endif
  369.          break;
  370.       case GLUT_KEY_DOWN:
  371.          xrot -= 3.0;
  372. #ifndef USE_ZBUFFER
  373.                  if ( xrot < 0 )        xrot = 0;
  374. #endif
  375.          break;
  376.       case GLUT_KEY_LEFT:
  377.          yrot += 3.0;
  378.          break;
  379.       case GLUT_KEY_RIGHT:
  380.          yrot -= 3.0;
  381.          break;
  382.    }
  383.    glutPostRedisplay();
  384. }
  385.  
  386.  
  387.  
  388. static void idle( void )
  389. {
  390.    spin += 2.0;
  391.    yrot += 3.0;
  392.    glutPostRedisplay();
  393. }
  394.  
  395.  
  396.  
  397. int main( int argc, char *argv[] )
  398. {
  399.    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB 
  400. #ifdef USE_ZBUFFER
  401.                 | GLUT_DEPTH 
  402. #endif
  403.                 | GLUT_STENCIL);
  404.    glutInitWindowPosition( 0, 0 );
  405.    glutInitWindowSize(400, 300 );
  406.    glutCreateWindow(argv[0]);
  407.    glutReshapeFunc(reshape);
  408.    glutDisplayFunc(draw_scene);
  409.    glutKeyboardFunc(Key);
  410.    glutSpecialFunc(SpecialKey);
  411.    glutIdleFunc(idle);
  412.  
  413.    init();
  414.  
  415.    glutMainLoop();
  416.    return 0;
  417. }
  418.